package org.example.mppg.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgis.Geometry;
import org.postgis.PGgeometry;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @description:
 * @author: bo
 * @create: 2025-07-14 23:20
 */
public abstract class MyPgGeometryTypeHandler<T extends Geometry> extends BaseTypeHandler<T> {
    /**
     * SRS-EPSG
     */
    private static final int EPSG_CODE = 4326;

    /**
     * 插入 - 插入时设置参数类型
     *
     * @param preparedStatement
     * @param i
     * @param parameter         org.postgis组织的几何类型实体
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, T parameter, JdbcType jdbcType) throws SQLException {
        boolean typeCheck = parameter instanceof Geometry;
        if (!typeCheck) {
            preparedStatement.setObject(i, null);
            System.out.println("MyBatis类型转换器插入参数非org.postgis.Geometry[Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon]");
        }

        PGgeometry pGgeometry = new PGgeometry(parameter);
        parameter.setSrid(EPSG_CODE);
        preparedStatement.setObject(i, pGgeometry);
    }

    /**
     * 获取 - 获取时转换回的自定义类型 - 根据列名获取
     *
     * @param resultSet
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
        // 获取读取到的指定列存储的值并进行类型检查
        Object result = resultSet.getObject(columnName);
        boolean typeCheck = result instanceof PGgeometry;
        if (!typeCheck) {
            System.out.println("MyBatis类型转换器获取参数转自定义类型错误，列实际存储类型非org.postgis.PGgeometry");
            return null;
        }
        return (T) ((PGgeometry) result).getGeometry();
    }

    /**
     * 获取 - 获取时转换回的自定义类型 - 根据索引位置获取
     *
     * @param resultSet
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public T getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
        // 获取读取到的指定列存储的值并进行类型检查
        Object result = resultSet.getObject(columnIndex);
        boolean typeCheck = result instanceof PGgeometry;
        if (!typeCheck) {
            System.out.println("MyBatis类型转换器获取参数转自定义类型错误，列实际存储类型非org.postgis.PGgeometry");
            return null;
        }
        return (T) ((PGgeometry) result).getGeometry();
    }

    /**
     * 获取 - 获取时转换回的自定义类型 - 根据存储过程获取
     *
     * @param callableStatement
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public T getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
        // 获取读取到的指定列存储的值并进行类型检查
        Object result = callableStatement.getObject(columnIndex);
        boolean typeCheck = result instanceof PGgeometry;
        if (!typeCheck) {
            System.out.println("MyBatis类型转换器获取参数转自定义类型错误，列实际存储类型非org.postgis.PGgeometry");
            return null;
        }
        return (T) ((PGgeometry) result).getGeometry();
    }
}
